import re
# Create your views here.
from django_redis import get_redis_connection
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from xj_users.models import Spit
from zwb_spit.serializers import SpitListSerializer


# 3.收藏或取消收藏视图
class SpitCollectViewSet(ModelViewSet):
    queryset = Spit.objects.all()
    serializer_class = SpitListSerializer

    # 收藏或取消收藏
    def update(self, request, *args, **kwargs):
        spit = self.get_object()
        user = request.user
        collected = request.data.get('collected')
        content_type = request.META['CONTENT_TYPE']
        authorization = request.META['HTTP_AUTHORIZATION']
        if not all(['content_type', 'authorization']):
            return Response({"message": "缺少必传参数", 'code': 400})
        if re.match(r'^JWT[\s][\w+]\.[\w+]\.[\w+]', authorization):
            return Response({"message": "参数HTTP_AUTHORIZATION有误",
                             "code": 400})
        if content_type != "application/json;charset=UTF-8":
            return Response({"message": "参数content_type有误",
                             "code": 400})
        redis_conn = get_redis_connection('collection')
        collection_flag = redis_conn.hget('spit_collect_%s' % user.id, spit.id)
        if collection_flag:
            redis_conn.hdel('spit_collect_%s' % user.id, spit.id)
            message = "取消收藏成功"
        else:
            redis_conn.hset('spit_collect_%s' % user.id, spit.id, 1)
            message = "收藏成功"
        return Response({"message": message,
                         "success": "True"},
                        status=200)


# 2.点赞或取消点赞
class SpitUpdateThumbUpViewSet(ModelViewSet):
    queryset = Spit.objects.all()
    serializer_class = SpitListSerializer

    # 点赞或取消点赞
    def update(self, request, *args, **kwargs):
        user = request.user
        spit = self.get_object()  # 获取当前点赞的吐槽对象
        content_type = request.META['CONTENT_TYPE']
        authorization = request.META['HTTP_AUTHORIZATION']
        if not all(['content_type', 'authorization']):
            return Response({"message": "缺少必传参数", "success": False},
                            status=400)
        if re.match(r'^JWT[\s][\w+]\.[\w+]\.[\w+]', authorization):
            return Response({"message": "参数HTTP_AUTHORIZATION有误",
                             "code": 400})
        if not user.is_authenticated:
            return Response({"message": "请登陆后再发表评论", "success": False},
                            status=400)
        if content_type != "application/json;charset=UTF-8":
            return Response({"message": "参数content_type有误",
                             "code": 400})
        redis_conn = get_redis_connection('like')
        hasthumbup_flag = redis_conn.hget('like_%s' % user.id, spit.id)
        if hasthumbup_flag:
            spit.thumbup -= 1
            message = "取消点赞成功"
            redis_conn.hdel('like_%s' % user.id, spit.id)
        else:
            redis_conn.hset('like_%s' % user.id, spit.id, 1)
            spit.thumbup += 1
            message = "点赞成功"
        try:
            spit.save()
        except Exception as e:
            return Response({"message": "保存到数据库出错", "success": False},
                            status=400)
        return Response({"message": message,
                         "success": "True"},
                        status=200)


# 1.获取吐槽列表； 2.发布新吐槽； 3.获取吐槽评论
class SpitModelViewSet(ModelViewSet):
    queryset = Spit.objects.all()
    serializer_class = SpitListSerializer
    permission_classes = [AllowAny]

    #  禁用DRF认证，未登录用户也能获取吐槽列表
    def perform_authentication(self, request):
        pass

    @action(methods=['GET'], detail=True, url_path="children", url_name='获取吐槽的评论')
    def retrieve_children(self, request, pk):
        spit_queryset = self.get_queryset().filter(parent=pk).order_by("-publishtime")
        spit_list = []
        try:
            user = request.user
        except Exception as e:
            user = None

        if  user is not None and user.is_authenticated:
            redis_conn1 = get_redis_connection('collection')
            redis_conn2 = get_redis_connection('like')
            for spit in spit_queryset:
                collection_flag = redis_conn1.hget('spit_collect_%s' % user.id, spit.id)
                hasthumbup_flag = redis_conn2.hget('like_%s' % user.id, spit.id)
                if collection_flag:
                    spit.collected = True
                if hasthumbup_flag:
                    spit.hasthumbup = True
                spit_list.append(spit)
        else:
            spit_list = spit_queryset
        serializer = self.get_serializer(instance=spit_list, many=True)
        return Response(serializer.data)

    def retrieve(self, request, *args, **kwargs):
        spit = self.get_object()
        spit.visits += 1
        spit.save()
        try:
            user = request.user
        except Exception as e:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn1 = get_redis_connection('collection')
            redis_conn2 = get_redis_connection('like')
            collection_flag = redis_conn1.hget('spit_collect_%s' % user.id, spit.id)
            hasthumbup_flag = redis_conn2.hget('like_%s' % user.id, spit.id)
            if collection_flag:
                spit.collected = True
            if hasthumbup_flag:
                spit.hasthumbup = True
        serializer = self.get_serializer(instance=spit)
        return Response(serializer.data)

    def list(self, request, *args, **kwargs):
        spit_queryset = self.get_queryset().filter(parent=None).order_by('-publishtime')
        try:
            user = request.user
        except Exception as e:
            user = None

        spit_list = []
        if user is not None and user.is_authenticated:
            redis_conn1 = get_redis_connection('collection')
            redis_conn2 = get_redis_connection('like')
            for spit in spit_queryset:
                collection_flag = redis_conn1.hget('spit_collect_%s' % user.id, spit.id)
                hasthumbup_flag = redis_conn2.hget('like_%s' % user.id, spit.id)
                if collection_flag:
                    spit.collected = True
                if hasthumbup_flag:
                    spit.hasthumbup = True
                spit_list.append(spit)
        else:
            spit_list = spit_queryset
        serializer = self.get_serializer(instance=spit_list, many=True)
        return Response(serializer.data)

